package mytaxis.move.calendar;

import java.util.Calendar;
import java.util.TimeZone;

import mytaxis.move.app.MyTaxisApplication;
import mytaxis.move.app.MyTaxisService;
import mytaxis.move.app.RequestReceivedActivity;
import mytaxis.move.map.DriverMap;
import mytaxis.move.model.MyTaxisModel;
import mytaxis.move.R;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.content.res.Resources;
import android.database.Cursor;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.IBinder;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.Gravity;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SimpleCursorAdapter;
import android.widget.TabHost;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;
import android.widget.Toast;

public class CalendarActivity extends Activity implements OnClickListener {

	private MyTaxisModel model;
	private MyTaxisApplication app;
	private MyTaxisService mBoundService;
	private Calendar cal;
	private int month;
	private int year;
	private int monthListStart;
	private int monthListEnd;
	private int yearListStart;
	private int yearListEnd;
	private int daysmonth;
	private int rows;
	private int values[][];
	private boolean[] hasTasks;
	private String[] monthName;
	private int[] numberOfDays;
	private String[] weekDay;
	private String[] status;
	private String listTitle;
	private boolean filterStatus = false;
	private String statusFiltered;

	private TabHost tabs;
	private TextView listEmpty;
	private TextView calTitle;
	private TextView listHead;
	private TextView listClick;
	private ListView listTasks;
	private ImageView prevMonth;
	private ImageView nextMonth;
	private Button loadNextTasks;
	private View footer;

	private Cursor taskClicked;
	
	private ServiceConnection mConnection = new ServiceConnection() {
		public void onServiceConnected(ComponentName className, IBinder service) {
			mBoundService = ((MyTaxisService.LocalBinder)service).getService();
		}

		public void onServiceDisconnected(ComponentName className) {
			mBoundService = null;
		}
	};

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		this.setContentView(R.layout.calendar);
		bindService(new Intent(this, MyTaxisService.class), mConnection, Context.BIND_AUTO_CREATE);	
		model = new MyTaxisModel(this);
		app = (MyTaxisApplication) getApplication();
		monthName = getResources().getStringArray(R.array.monthName);
		numberOfDays = getResources().getIntArray(R.array.daysMonth);
		weekDay = getResources().getStringArray(R.array.weekDay);
		status = getResources().getStringArray(R.array.status);

		initVariables();
		initViews();
		fillCalendar();
		fillList();
	}
	
	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.calendarmenu, menu);
		return true;
	}
	
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case R.id.optionsReset:
			Calendar cal = Calendar.getInstance();
			cal.setTimeZone(TimeZone.getTimeZone("Europe/Madrid"));
			monthListStart = cal.get(Calendar.MONTH);
			monthListEnd = monthListStart;
			yearListStart = cal.get(Calendar.YEAR);
			yearListEnd = yearListStart;
			listTitle=monthName[monthListStart]+" "+yearListStart;
			app.setMonthListStart(monthListStart);
			app.setMonthListEnd(monthListEnd);
			app.setYearListStart(yearListStart);
			app.setYearListEnd(yearListEnd);
			app.setListTitle(listTitle);
			fillList();
			return true;
		default:
			return super.onOptionsItemSelected(item);
		}
	}

	private void initVariables() {
		cal = Calendar.getInstance();
		cal.setTimeZone(TimeZone.getTimeZone("Europe/Madrid"));
		if (app.getMonth() == -1) {
			month = cal.get(Calendar.MONTH);
			year = cal.get(Calendar.YEAR);
			app.setMonth(month);
			app.setYear(year);
		} else {
			month = app.getMonth();
			year = app.getYear();
			cal.set(Calendar.MONTH, month);
			cal.set(Calendar.YEAR, year);
		}
		cal.set(Calendar.DAY_OF_MONTH, 1);
		int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
		if (dayOfWeek == 1)
			dayOfWeek = 7;
		else
			dayOfWeek--;
		daysmonth = numberOfDays[month];
		if (month == 1 && year % 4 == 0 && (year % 100 != 0 || year % 400 == 0))
			daysmonth++;
		fillValues(dayOfWeek);
		if (app.getMonthListStart() == -1) {
			monthListStart = month;
			monthListEnd = month;
			yearListStart = year;
			yearListEnd = year;
			listTitle = monthName[monthListStart] + " " + yearListStart;
			app.setMonthListStart(monthListStart);
			app.setMonthListEnd(monthListEnd);
			app.setYearListStart(yearListStart);
			app.setYearListEnd(yearListEnd);
			app.setListTitle(listTitle);
		} else {
			monthListStart = app.getMonthListStart();
			monthListEnd = app.getMonthListEnd();
			yearListStart = app.getYearListStart();
			yearListEnd = app.getYearListEnd();
			listTitle = app.getListTitle();
		}
		if (app.isFilterStatus()) {
			filterStatus = true;
			statusFiltered = app.getStatusFiltered();
		}
	}

	private void fillValues(int dayOfWeek) {
		values = new int[6][7];
		int daysPlaced = 0;
		rows = 0;
		for (int i = 0; i < 6; i++) {
			for (int j = 0; j < 7; j++) {
				if (daysPlaced == 0 && j == dayOfWeek - 1) {
					daysPlaced++;
					values[i][j] = daysPlaced;
				} else if (daysPlaced > 0 && daysPlaced < daysmonth) {
					daysPlaced++;
					values[i][j] = daysPlaced;
				} else if (rows == 0 && daysPlaced == daysmonth) {
					rows = i;
					if (j == 0)
						rows--;
				} else {
					values[i][j] = 0;
				}
			}
		}
	}

	private void initViews() {
		Resources res = getResources();
		tabs = (TabHost) findViewById(android.R.id.tabhost);
		tabs.setup();
		TabHost.TabSpec spec = tabs.newTabSpec("mitab1");
		spec.setContent(R.id.calendarTab);
		spec.setIndicator("Calendar",
				res.getDrawable(android.R.drawable.ic_btn_speak_now));
		tabs.addTab(spec);
		spec = tabs.newTabSpec("mitab2");
		spec.setContent(R.id.listTab);
		spec.setIndicator("List",
				res.getDrawable(android.R.drawable.ic_dialog_map));
		tabs.addTab(spec);

		tabs.setCurrentTab(0);

		calTitle = (TextView) findViewById(R.id.month);
		listHead = (TextView) findViewById(R.id.listHeader);
		listEmpty = (TextView) findViewById(R.id.listEmpty);
		listClick = (TextView) findViewById(R.id.listClick);
		listTasks = (ListView) findViewById(R.id.tlist);
		prevMonth = (ImageView) findViewById(R.id.prevmonth);
		nextMonth = (ImageView) findViewById(R.id.nextMonth);
		loadNextTasks = (Button) findViewById(R.id.addNextTasks);
		footer = getLayoutInflater().inflate(R.layout.tasklist_last, null);

		registerForContextMenu(listTasks);

		prevMonth.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				month--;
				if (month < 0) {
					month = 11;
					year--;
				}
				app.setMonth(month);
				app.setYear(year);
				cal.set(Calendar.MONTH, month);
				cal.set(Calendar.YEAR, year);
				int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
				if (dayOfWeek == 1)
					dayOfWeek = 7;
				else
					dayOfWeek--;
				daysmonth = numberOfDays[month];
				if (month == 1 && year % 4 == 0
						&& (year % 100 != 0 || year % 400 == 0))
					daysmonth++;
				fillValues(dayOfWeek);
				fillCalendar();
			}
		});

		nextMonth.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				month++;
				if (month > 11) {
					month = 0;
					year++;
				}
				app.setMonth(month);
				app.setYear(year);
				cal.set(Calendar.MONTH, month);
				cal.set(Calendar.YEAR, year);
				int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
				if (dayOfWeek == 1)
					dayOfWeek = 7;
				else
					dayOfWeek--;
				daysmonth = numberOfDays[month];
				fillValues(dayOfWeek);
				fillCalendar();
			}
		});

		footer.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				loadNextTasks();
			}
		});

		loadNextTasks.setOnClickListener(new OnClickListener() {
			public void onClick(View v) {
				loadNextTasks();
			}
		});
		
		listTasks.setOnItemClickListener(new OnItemClickListener() {
			public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
				if(mBoundService.hasActiveRequest()){
					Toast.makeText(getApplicationContext(), R.string.click_has_active, Toast.LENGTH_LONG).show();
				}else{
					taskClicked = (Cursor) listTasks.getAdapter().getItem(position);
					
					if(taskClicked.getString(3).equals(status[0])){
						Bundle b = new Bundle();
						b.putDouble("posX", taskClicked.getDouble(5));
						b.putDouble("posY", taskClicked.getDouble(6));
						Intent i = new Intent(CalendarActivity.this,DriverMap.class);
						i.putExtras(b);
						startActivity(i);
						finish();
					}else{
						Toast.makeText(getApplicationContext(), R.string.click_not_scheduled, Toast.LENGTH_LONG).show();
					}
				}				
			}
		});
	}

	private void loadNextTasks() {
		monthListEnd++;
		if (monthListEnd == 12) {
			monthListEnd = 0;
			yearListEnd++;
		}
		listTitle = monthName[monthListStart] + " " + yearListStart + " to "
				+ monthName[monthListEnd] + " " + yearListEnd;
		app.setMonthListEnd(monthListEnd);
		app.setYearListEnd(yearListEnd);
		app.setListTitle(listTitle);
		fillList();
	}

	@Override
	public void onCreateContextMenu(ContextMenu menu, View v,
			ContextMenuInfo menuInfo) {
		super.onCreateContextMenu(menu, v, menuInfo);
		String[] menuItems = getResources().getStringArray(R.array.contexttask);
		for (int i = 0; i < menuItems.length; i++) {
			menu.add(Menu.NONE, i, i, menuItems[i]);
		}
	}

	@Override
	public boolean onContextItemSelected(MenuItem item) {
		AdapterContextMenuInfo info = (AdapterContextMenuInfo) item
				.getMenuInfo();
		ListAdapter l = listTasks.getAdapter();
		taskClicked = (Cursor) l.getItem(info.position);
		if(item.getItemId() == 0){
			if (taskClicked.getString(3).equals(status[1]) || taskClicked.getString(3).equals(status[3])) {
				Toast.makeText(this, R.string.cancel_canceled, Toast.LENGTH_LONG).show();
			} else if (taskClicked.getString(3).equals(status[2])) {
				Toast.makeText(this, R.string.cancel_completed, Toast.LENGTH_LONG).show();
			} else if (taskClicked.getString(3).equals(status[0])) {
				AlertDialog.Builder alertbox = new AlertDialog.Builder(this);
				alertbox.setMessage(R.string.cancel_confirm);
	
				alertbox.setNegativeButton(R.string.no,
						new DialogInterface.OnClickListener() {
							public void onClick(DialogInterface arg0, int arg1) {
							}
	
						});
	
				alertbox.setPositiveButton(R.string.yes,
						new DialogInterface.OnClickListener() {
							public void onClick(DialogInterface arg0, int arg1) {
								long time = Long.parseLong(taskClicked.getString(1));
								long now = model.getNowTime();
								if ((time - 12 * 3600) > now) {
									if(mBoundService.acceptRequest(false, taskClicked.getString(0))){
										model.updateStatus(taskClicked.getString(0),
												status[1]);
										taskClicked.requery();
									}else{
										Toast.makeText(getApplicationContext(),R.string.connection_error,0).show();
									}
								} else {
									Toast.makeText(CalendarActivity.this,
											R.string.cancel_timeout,
											Toast.LENGTH_LONG).show();
								}
	
							}
						});
				alertbox.show();
			}
		}
		else if(item.getItemId() == 1){
			if (taskClicked.getString(3).equals(status[1]) || taskClicked.getString(4).equals(status[3])) {
				Toast.makeText(this, R.string.complete_canceled, Toast.LENGTH_LONG).show();
			} else if (taskClicked.getString(3).equals(status[2])) {
				Toast.makeText(this, R.string.complete_completed, Toast.LENGTH_LONG).show();
			} else if (taskClicked.getString(3).equals(status[0])) {
				AlertDialog.Builder alertbox = new AlertDialog.Builder(this);
				alertbox.setMessage(R.string.complete_confirm);
	
				alertbox.setNegativeButton(R.string.no,
						new DialogInterface.OnClickListener() {
							public void onClick(DialogInterface arg0, int arg1) {
							}
	
						});
	
				alertbox.setPositiveButton(R.string.yes,
						new DialogInterface.OnClickListener() {
							public void onClick(DialogInterface arg0, int arg1) {
								long time = Long.parseLong(taskClicked.getString(1));
								long now = model.getNowTime();
								if (time <= now) {
									if(mBoundService.endRequest(taskClicked.getString(0))){
										model.updateStatus(taskClicked.getString(0),status[2]);
										taskClicked.requery();
									}
								} else {
									Toast.makeText(CalendarActivity.this,
											R.string.complete_too_soon,
											Toast.LENGTH_LONG).show();
								}
	
							}
						});
				alertbox.show();
			}
		}
		return true;
	}

	private void fillCalendar() {
		calTitle.setText(monthName[month] + " " + year);
		fillHasTasks();
		TableLayout table = (TableLayout) findViewById(R.id.tcalendar);
		Drawable border = getResources().getDrawable(R.drawable.fulldayborder);
		Drawable weekbg = getResources().getDrawable(R.drawable.weekbackground);
		Drawable columnbg = getResources()
				.getDrawable(R.drawable.daybackground);
		Drawable taskbg = getResources().getDrawable(R.drawable.bgdaytask);
		table.removeAllViews();
		TableRow tr = new TableRow(this);
		for (int i = 0; i < 8; i++) {
			TextView tv = new TextView(this);
			if (i > 0) {
				tv.setBackgroundDrawable(columnbg);
				tv.setText(weekDay[i]);
				tv.setTextColor(Color.BLACK);
				tv.setClickable(true);
				tv.setGravity(Gravity.CENTER);
				tv.setWidth(20);
				tv.setHeight(50);
			}
			tr.addView(tv);
		}
		table.addView(tr);
		for (int i = 0; i <= rows; i++) {
			tr = new TableRow(this);
			for (int j = 0; j < 8; j++) {
				TextView tv = new TextView(this);
				if (j == 0) {
					tv.setText(String.valueOf(i + 1));
					tv.setBackgroundDrawable(weekbg);
					tv.setTextColor(Color.BLACK);
					tv.setWidth(25);
					tv.setClickable(true);
				} else {
					if (values[i][j - 1] != 0) {
						tv.setText(String.valueOf(values[i][j - 1]));
						tv.setClickable(true);
						tv.setOnClickListener(this);
						if (hasTasks[values[i][j - 1]]) {
							tv.setBackgroundDrawable(taskbg);
						} else
							tv.setBackgroundDrawable(border);
					} else
						tv.setBackgroundDrawable(border);
					tv.setWidth(40);
				}
				tv.setGravity(Gravity.CENTER);
				tv.setHeight(50);
				tr.addView(tv);
			}
			table.addView(tr);
		}
	}

	private void fillHasTasks() {
		hasTasks = new boolean[daysmonth + 1];
		Cursor c = model.getTasksMonth(month, month, year, year, daysmonth,
				filterStatus, statusFiltered);
		if (c.moveToFirst()) {
			do {
				String date = c.getString(1);
				Calendar start = Calendar.getInstance();
				start.setTimeInMillis(Long.parseLong(date) * 1000);
				int day = start.get(Calendar.DAY_OF_MONTH);
				hasTasks[day] = true;
			} while (c.moveToNext());
		}
		c.close();
	}

	public void onClick(View v) {
		TextView tv = (TextView) v;
		String num = tv.getText().toString();
		listTitle = num + "-" + (month + 1) + "-" + year;
		app.setListTitle(listTitle);
		fillList();
		tabs.setCurrentTab(1);
	}

	private void fillList() {
		listHead.setText("Tasks from " + listTitle);
		if (listTasks.getFooterViewsCount() > 0)
			listTasks.removeFooterView(footer);

		if (listTitle.matches("[0-9]*-[0-9]*-[0-9]*")) {
			String day = listTitle.split("-")[0];
			Cursor c = model.getTasksDay(Integer.parseInt(day), month, year,
					filterStatus, statusFiltered);
			if (c.getCount() == 0)
				listEmpty.setText(getString(R.string.no_tasks_stored));
			else {
				loadNextTasks.setVisibility(View.GONE);
				listEmpty.setText("");
			}
			String[] from = new String[] { "ubicacio", "datahorastring", "estat" };
			int[] to = new int[] { R.id.name_row, R.id.date_row,
					R.id.status_row };
			SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
					R.layout.tasklist_row, c, from, to);
			listTasks.setAdapter(adapter);
			startManagingCursor(c);
			listClick.setText(getString(R.string.load_month));
			listClick.setOnClickListener(new OnClickListener() {
				public void onClick(View arg0) {
					if (monthListStart == monthListEnd
							&& yearListStart == yearListEnd)
						listTitle = monthName[monthListStart] + " "
								+ yearListStart;
					else
						listTitle = monthName[monthListStart] + " "
								+ yearListStart + " to "
								+ monthName[monthListEnd] + " " + yearListEnd;
					app.setListTitle(listTitle);
					fillList();
				}
			});
		} else {
			int daysLastMonth = numberOfDays[monthListEnd];
			if (monthListEnd == 1 && yearListEnd % 4 == 0
					&& (yearListEnd % 100 != 0 || yearListEnd % 400 == 0))
				daysLastMonth++;
			Cursor c = model.getTasksMonth(monthListStart, monthListEnd,
					yearListStart, yearListEnd, daysLastMonth, filterStatus,
					statusFiltered);

			if (c.getCount() == 0) {
				listEmpty.setText(getString(R.string.no_tasks_stored));
				loadNextTasks.setVisibility(View.VISIBLE);
			} else {
				listTasks.addFooterView(footer);
				loadNextTasks.setVisibility(View.GONE);
				listEmpty.setText("");
			}
			String[] from = new String[] { "ubicacio", "datahorastring",
					"estat", "ubicacio" };
			int[] to = new int[] { R.id.name_row, R.id.date_row,
					R.id.status_row, };
			SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
					R.layout.tasklist_row, c, from, to);
			listTasks.setAdapter(adapter);
			startManagingCursor(c);
			listClick.setText(getString(R.string.load_previous_month));
			listClick.setOnClickListener(new OnClickListener() {
				public void onClick(View arg0) {
					monthListStart--;
					if (monthListStart < 0) {
						monthListStart = 11;
						yearListStart--;
					}
					listTitle = monthName[monthListStart] + " " + yearListStart
							+ " to " + monthName[monthListEnd] + " "
							+ yearListEnd;
					app.setMonthListStart(monthListStart);
					app.setYearListStart(yearListStart);
					app.setListTitle(listTitle);
					fillList();
				}
			});
		}
	}
	
	private BroadcastReceiver myReceiverSol = new BroadcastReceiver() {

		@Override
		public void onReceive(Context context, Intent intent) {
			Bundle extras = intent.getExtras();				
			String data = extras.getString(MyTaxisService.IMM_REQ_DATA);
			if(data.equals("1")){
				Intent i = new Intent(CalendarActivity.this, RequestReceivedActivity.class);
				startActivity(i);
			}
		}
	};

	private void doRegister(){
		IntentFilter filter = new IntentFilter(MyTaxisService.IMM_REQ_FILTER);
		registerReceiver(myReceiverSol, filter);
	}

	private void doUnRegister(){
		unregisterReceiver(myReceiverSol);
	}
	
	@Override
	protected void onResume() {
		super.onResume();
		doRegister();
	}

	@Override
	protected void onPause() {
		super.onPause();
		doUnRegister();
	}


	@Override
	protected void onDestroy() {
		super.onDestroy();
		model.closeDB();
		unbindService(mConnection);
	}
}
